﻿using GN.Pay.TradeChannel.DefaultImpl;
using GN.Pay.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GN.Pay.TradeChannel.YJPay.Response
{
    [Serializable]
    public class QueryResponse : AResponse
    {
        /// <summary>
        /// 查询响应
        /// </summary>
        private readonly ITradeChannel channel;
        private readonly YJPayConfigure config;

        public QueryResponse(string responseString,
            ITradeChannel channel,
            YJPayConfigure config)
        {
            if (responseString != null)
            {
                this.ResponseString = responseString.Trim();
            }
            else
            {
                this.ResponseString = responseString;
            }
            this.channel = channel;
            this.config = config;

        }

        private static string Format_ErrorMessage = "响应结果格式不正确，没有该订单号的订单信息。";


        private QueryResponseEntity ToEntity(string responseString)
        {
            if (string.IsNullOrWhiteSpace(responseString))
            {
                this.channel.ThrowInterfaceException(Format_ErrorMessage);
            }
            QueryResponseEntity result;
            try
            {
                result = QueryResponseEntity.Create(ResponseString);
            }
            catch
            {
                throw channel.ThrowInterfaceException(Format_ErrorMessage);
            }

            if (string.IsNullOrEmpty(result.resultCode))
            {
                throw this.channel.ThrowInterfaceException(Format_ErrorMessage);
            }
            if (!result.SignVeryfy(responseString, config.ConfigureInfo.Key))
            {
                throw this.channel.ThrowChannelValidationException("签名验证失败！");
            }
            if (result.resultCode.Equals("EXECUTE_SUCCESS", StringComparison.InvariantCultureIgnoreCase) &&
                "true".Equals(result.success))
            {
                this.IsSuccess = true;
            }
            else
            {
                this.IsSuccess = false;
                if (string.IsNullOrEmpty(result.resultMessage))
                {
                    this.ErrorCode = result.resultMessage;
                }
                else
                {
                    this.ErrorCode = "";
                }
            }
            return result;
        }

        /// <summary>
        /// 查询响应体
        /// </summary>
        public string ResponseString { get; private set; }

        /// <summary>
        /// 是否成功
        /// </summary>
        public bool IsSuccess { get; set; }

        /// <summary>
        /// 错误码
        /// </summary>
        public string ErrorCode { get; set; }

        /// <summary>
        /// 转为结果
        /// </summary>      
        /// <returns></returns>
        public ITradeOrderQueryResult ToResult()
        {
            var entity = ToEntity(this.ResponseString);
            if (entity.totalCount > 0 && entity.successCount > 0
                && entity.singleTradeInfos != null
                && entity.singleTradeInfos.Count > 0)
            {
                var item = entity.singleTradeInfos[0];
                if (!item.IsPaySuccess())
                {
                    return null;
                }
                decimal refundMoney = item.refundInfos != null ? item.refundInfos.Sum(s => s.refundAmount) : 0m;
                var result = new TradeOrderQueryResult(channel)
                {
                    BankName = "",
                    BankType = "",
                    Body = "",
                    Subject = item.goodsName,
                    ChannelMode = "ONLINEBANK",
                    ExtraParam = "",
                    OrderMoney = item.payAmount,
                    OrderNo = item.merchOrderNo,
                    OtherPartyAccount = "",
                    OtherPartyAccountId = "",
                    PayFee = 0m,
                    PayTime = item.finishTime,
                    RefundFee = 0m,
                    TradeNo = item.tradeNo,
                    RefundMoney = refundMoney
                };
                return result;
            }
            else
            {
                return null;
            }
        }
    }
}
